#coding:utf-8
'''
create on 2017-08-22
@author:sandy
'''

import logging
import random

g_NeedHunCount = 4
callTime = 0

def isValidMj(sid):
    t = sid / 100
    c = sid % 100 / 10 # 忽略该字段，仅用于判别有效  
    v = sid % 10
    if t == 1 or t == 2 or t == 3:
        if v < 1 or v > 9:
            return False
        else:
            return True
    elif t == 4:
        if v < 1 or v > 7:
            return False
        else:
            return True
    else:
        return True


def sortArr(arr):
    if len(arr) == 0:  
        return  
    arr.sort(None,key=lambda v:v%10)


def seprateArr(sidArr,hunSid):
    reArr = [[],[],[],[],[]]
    ht = hunSid / 100
    hv = hunSid % 10
    for sid in sidArr:
        t = sid / 100
        v = sid % 10
        if ht == t and hv == v:
            t = 0
        reArr[t].append(sid)
        sortArr(reArr[t])
    return reArr

def test3Combine(sid1,sid2,sid3):
    t1, t2, t3 = sid1 / 100,sid2 / 100,sid3 / 100 
    # 牌型不同不能组合
    if t1 != t2 or t1 != t3:
        return False
    v1,v2,v3 = sid1 % 10,sid2 % 10,sid3 % 10
    # 重牌
    if v1 == v2 and v1 == v3:
        return True
    if t3 == 4:
        return False
    if(v1 + 1 == v2 and v1 + 2 == v3):
        return True
    return False

def getModNeedNum(arrLem,isJiang):
    if arrLem <=0:  
        return 0  
    modNum = arrLem % 3  
    needNumArr = [0,2,1]  
    if isJiang:  
        needNumArr = [2,1,0] 
    return needNumArr[modNum]


def getNeedHunInSub(subArr,hNum):
    global callTime  
    callTime += 1
    global g_NeedHunCount
    if g_NeedHunCount == 0:
        return
    lArr = len(subArr)
    if hNum + getModNeedNum(lArr,False) >= g_NeedHunCount:
        return
    if lArr == 0:  
        g_NeedHunCount = min( hNum, g_NeedHunCount)  
        return  
    elif lArr == 1:
        g_NeedHunCount = min( hNum+2, g_NeedHunCount)
        return
    elif lArr == 2:
        t = subArr[0] / 100
        v0 = subArr[0] % 10
        v1 = subArr[1] % 10
        if t == 4:# 东南西北中发白
            if v0 == v1:
                g_NeedHunCount = min(hNum + 1,g_NeedHunCount)
                return
        elif (v1-v0) < 3:
            g_NeedHunCount = min( hNum+1, g_NeedHunCount )  
        return
    elif lArr >= 3:
        t = subArr[0] / 100
        v0 = subArr[0] % 10
        v2 = subArr[2] % 10
        arrLen = len(subArr)
        for i in range(1,arrLen):
            if hNum + getModNeedNum(lArr - 3,False) >= g_NeedHunCount:
                break
            v1 = subArr[i] % 10
            if v1 - v0 > 1:
                break
            if i + 2 < arrLen:
                if(subArr[i+2] % 10 == v1):
                    continue
            if i + 1 < arrLen:
                tmp1,tmp2,tmp3 = subArr[0],subArr[i],subArr[i+1]
                if test3Combine(tmp1,tmp2,tmp3):
                    subArr.remove(tmp1)
                    subArr.remove(tmp2)
                    subArr.remove(tmp3)
                    getNeedHunInSub(subArr,hNum)
                    subArr.append(tmp1)
                    subArr.append(tmp2)
                    subArr.append(tmp3)
                    sortArr(subArr)
        
        v1 = subArr[1] % 10
        if hNum + getModNeedNum(lArr - 2,False) + 1 < g_NeedHunCount:
            if t== 4:
                if v0 == v1:
                    tmp1 = subArr[0]
                    tmp2 = subArr[1]
                    subArr.remove(tmp1)
                    subArr.remove(tmp2)
                    getNeedHunInSub(subArr,hNum + 1)
                    subArr.append(tmp1)
                    subArr.append(tmp2)
                    sortArr(subArr)
            else:
                arrLen= len(subArr)
                for i in range(1,arrLen):
                    if hNum + getModNeedNum(lArr - 2,False) + 1 < g_NeedHunCount:
                        break
                    v1 = subArr[i] % 10
                    #如果当前的value不等于下一个value则和下一个结合避免重复
                    if (i + 1) != arrLen:
                        v2 = subArr[i+1] % 10
                        if v1 == v2:
                            continue
                    mius = v1 - v0
                    if mius < 3:
                        tmp1 = subArr[0]
                        tmp2 = subArr[i]
                        subArr.remove(tmp1)
                        subArr.remove(tmp2)
                        getNeedHunInSub(subArr,hNum + 1)
                        subArr.append(tmp1)
                        subArr.append(tmp2)
                        sortArr(subArr)
                        if mius >= 1:
                            break
                    else:
                        break
        
        if hNum + getModNeedNum(lArr - 1,False) + 2 < g_NeedHunCount:
            tmp = subArr[0]
            subArr.remove(tmp)
            getNeedHunInSub(subArr,hNum + 2)
            subArr.append(tmp)
            sortArr(subArr)
    else:
        return

def test2Combine(mj1,mj2):
    t1,t2 = mj1 / 100,mj2 / 100
    v1,v2 = mj1 % 10,mj2 % 10
    if t1 == t2 and v1 == v2 :
        return True
    return False

def canHu(hunNum,arr):
    global g_NeedHunCount
    tmpArr = []
    tmpArr.extend(arr)
    arrLen = len(tmpArr)
    if arrLen <= 0:
        if hunNum >= 2:
            return True
        return False
    if hunNum < getModNeedNum(arrLen,True):
        return False
    for i in range(arrLen):
        if i == (arrLen - 1):# 如果是最后一张牌
            if hunNum > 0:
                tmp = tmpArr[i]
                hunNum = hunNum - 1
                tmpArr.remove(tmpArr[i])
                g_NeedHunCount = 4
                getNeedHunInSub(tmpArr,0)
                if g_NeedHunCount <= hunNum:
                    return True
                hunNum = hunNum + 1
                tmpArr.append(tmp)
                sortArr(tmpArr)

        else:
            if(i + 2) == arrLen or (tmpArr[i] % 10 != tmpArr[i+2]%10):
                if test2Combine(tmpArr[i],tmpArr[i+1]):
                    tmp1 = tmpArr[i]
                    tmp2 = tmpArr[i+1]
                    tmpArr.remove(tmp1)
                    tmpArr.remove(tmp2)
                    g_NeedHunCount = 4
                    getNeedHunInSub(tmpArr,0)
                    if g_NeedHunCount <= hunNum:
                        return True
                    tmpArr.append(tmp1)
                    tmpArr.append(tmp2)
                    sortArr(tmpArr)
            if hunNum > 0 and (tmpArr[i] % 10 != tmpArr[i+1] % 10):
                hunNum = hunNum - 1
                tmp = tmpArr[i]
                tmpArr.remove(tmp)
                g_NeedHunCount = 4
                getNeedHunInSub(tmpArr,0)
                if g_NeedHunCount <= hunNum:
                    return True
                hunNum = hunNum + 1
                tmpArr.append(tmp)
                sortArr(tmpArr)
    return False


def testHu(mj,mjArr,hunMj):
    global g_NeedHunCount
    tmpArr = []
    tmpArr.extend(mjArr)
    if mj != 0:
        tmpArr.append(mj)
    sptArr = seprateArr(tmpArr,hunMj)
    curHunNum = len(sptArr[0])
    if curHunNum > 3:
        return True
    ndHunArr = []
    for i in range(1,5):
        g_NeedHunCount = 4
        getNeedHunInSub(sptArr[i],0)
        ndHunArr.append(g_NeedHunCount)
    isHu = False
    #万
    ndHunAll = ndHunArr[1] + ndHunArr[2] + ndHunArr[3]
    if ndHunAll <= curHunNum:
        hasNum = curHunNum - ndHunAll
        isHu = canHu(hasNum,sptArr[1])
        if isHu:
            return True
    #条
    ndHunAll = ndHunArr[0] + ndHunArr[2] + ndHunArr[3]
    if ndHunAll <= curHunNum:
        hasNum = curHunNum - ndHunAll
        isHu = canHu(hasNum,sptArr[2])
        if isHu:
            return True
    #饼
    ndHunAll = ndHunArr[0] + ndHunArr[1] + ndHunArr[3]
    if ndHunAll <= curHunNum:
        hasNum = curHunNum - ndHunAll
        isHu = canHu(hasNum,sptArr[3])
        if isHu:
            return True

    #字
    ndHunAll = ndHunArr[0] + ndHunArr[1] + ndHunArr[2]
    if ndHunAll <= curHunNum:
        hasNum = curHunNum - ndHunAll
        isHu = canHu(hasNum,sptArr[4])
        if isHu:
            return True

    return False

def testGang(mj,mjArr,hunMj):
    t = mj / 100
    v = mj % 10
    c = 0
    tmpArr = []
    tmpArr.append(mjArr)
    sptArr = seprateArr(tmpArr,hunMj)
    if len(sptArr[t]) < 2:
        return False
    else:
        for tmj in sptArr[t]:
            if (tmj % 10) == v:
                c = c + 1
        if c == 3:
            return True

def testPeng(mj,mjArr,hunMj):
    t = mj / 100
    v = mj % 10
    c = 0
    tmpArr = []
    tmpArr.append(mjArr)
    sptArr = seprateArr(tmpArr,hunMj)
    if len(sptArr[t]) < 2:
        return False
    else:
        for tmj in sptArr[t]:
            if (tmj % 10) == v:
                c = c + 1
        if c == 2 or c == 3:
            return True
    return False

def analyzeAnGang(mjArr,hunMj):
    result = []
    tmpArr = []
    tmpArr.extend(mjArr)
    sptArr = seprateArr(tmpArr,hunMj)
    for i in range(len(sptArr)):
        subLen = len(sptArr[i])
        if subLen < 4:
            continue
        else:
            for j in range(subLen):
                if(subLen - 1 - j) < 3:
                    break
                if(sptArr[i][j] % 10) == (sptArr[i][j+1] % 10) and (sptArr[i][j+1]%10 == sptArr[i][j+2]%10) and (sptArr[i][j+2]%10 ==  sptArr[i][j+3]%10):
                    result.append( sptArr[i][j] )
    return result

def rmSample(mj, mjArr, cnt=0):
    i = cnt 
    j = 0  
    while i>0:  
        if mjArr.count( mj ):  
            mjArr.remove( mj )  
            j += 1  
        i -= 1  
    return j  

def getJiangNeedHum(arr):
    global g_NeedHunCount  
    minNeedNum = 4  
    tmpArr = []  
    tmpArr.extend(arr)  
    arrLen  = len( tmpArr )  
    if arrLen <= 0:  
        return 2  
    for i in range( arrLen ):  
        if i == (arrLen - 1 ):# 如果是最后一张牌  
            tmp = tmpArr[i] 
            tmpArr.remove( tmpArr[i] )  
            g_NeedHunCount = 4  
            getNeedHunInSub(tmpArr, 0)  
            minNeedNum = min(minNeedNum,g_NeedHunCount+1)  
            tmpArr.append(tmp)  
            sortArr(tmpArr)  
        else:  
            if ( i+2 ) == arrLen or (tmpArr[i]%10) != (tmpArr[i+2]%10):  
                if test2Combine( tmpArr[i], tmpArr[i+1] ):  
                    tmp1 = tmpArr[i]  
                    tmp2 = tmpArr[i+1]  
                    tmpArr.remove( tmp1 )  
                    tmpArr.remove( tmp2 )  
                    g_NeedHunCount = 4  
                    getNeedHunInSub(tmpArr, 0)  
                    minNeedNum = min(minNeedNum,g_NeedHunCount)  
                    tmpArr.append( tmp1 )  
                    tmpArr.append( tmp2 )  
                    sortArr(tmpArr)  
            if (tmpArr[i]%10) != (tmpArr[i+1]%10): 
                tmp = tmpArr[i]  
                tmpArr.remove( tmp )  
                g_NeedHunCount = 4  
                getNeedHunInSub(tmpArr, 0)  
                minNeedNum = min(minNeedNum,g_NeedHunCount+1)  
                tmpArr.append( tmp )  
                sortArr( tmpArr )  
    return minNeedNum  

#摸哪些牌能胡牌
def getTingArr(mjArr,hunMj):  
    global g_NeedHunCount  
    global callTime  
    tmpArr = []  
    tmpArr.extend(mjArr) # 创建一个麻将数组的copy  
    sptArr = seprateArr( tmpArr, hunMj )  
    ndHunArr = [] # 每个分类需要混的数组  
    for i in range( 1, 5 ):  
        g_NeedHunCount = 4  
        getNeedHunInSub( sptArr[i], 0 )  
        ndHunArr.append(g_NeedHunCount)  
    jaNdHunArr = []#每个将分类需要混的数组  
    for i in range(1,5):  
        jdNeedHunNum = getJiangNeedHum(sptArr[i])  
        jaNdHunArr.append(jdNeedHunNum)  

    curHunNum = len( sptArr[0])  
    tingArr = []  
    paiArr = [[101,110],[201,210],[301,310],[401,408]]
    #是否单调将  
    isAllHu = False  
    needNum = 0  
    for i in range(0,4):  
        needNum += ndHunArr[i]
    if curHunNum - needNum == 1:  
        isAllHu = True  
    if isAllHu:  
        for lis in paiArr:  
            for x in range(lis[0],lis[1]):  
                tingArr.append(x)  
        return  tingArr  

    for i in range(0,4):  
        # if len(sptArr[i+1]) == 0:  
        #     continue;  
        # 听牌是将  
        needNum = 0  
        for j in range(0,4):  
            if(i != j):  
                needNum = needNum + ndHunArr[j]  
        if needNum <= curHunNum:  
            for k in range(paiArr[i][0],paiArr[i][1]):  
                t = [k]  
                t.extend(sptArr[i+1])  
                sortArr(t)  
                if canHu(curHunNum-needNum,t):  
                    tingArr.append(k)  
                    # print callTime  
        # 听牌是扑  
        for j in range(0,4):  
            if(i != j):  
                needNum = 0  
                for k in range(0,4):  
                    if(k != i):  
                        if(k == j):  
                            needNum += jaNdHunArr[k]  
                        else:  
                            needNum += ndHunArr[k]  
                if needNum <= curHunNum:  
                    for k in range(paiArr[i][0],paiArr[i][1]):  
                        if k not in tingArr:  
                            t = [k]  
                            t.extend(sptArr[i+1])  
                            g_NeedHunCount = 4  
                            sortArr(t)  
                            getNeedHunInSub(t, 0 )  
                            if g_NeedHunCount <= curHunNum - needNum:  
                                tingArr.append(k)
    if(len(tingArr) > 0) and hunMj not in tingArr:  
        tingArr.append(hunMj)

    return  tingArr;  


#打哪些牌能听牌
def getTingNumArr(mjArr,hunMj):  
    global g_NeedHunCount  
    global callTime  
    tmpArr = []  
    tmpArr.extend(mjArr) # 创建一个麻将数组的copy  
    sptArr = seprateArr( tmpArr, hunMj )  
  
    ndHunArr = [] # 每个分类需要混的数组  
    for i in range( 1, 5 ):  
        g_NeedHunCount = 4  
        getNeedHunInSub( sptArr[i], 0 )  
        ndHunArr.append(g_NeedHunCount)  
    jaNdHunArr = []#每个将分类需要混的数组  
    for i in range(1,5):  
        jdNeedHunNum = getJiangNeedHum(sptArr[i])  
        jaNdHunArr.append(jdNeedHunNum)  
  
    #给一个混看能不能胡  
    curHunNum = len( sptArr[0])+1  
    tingArr = []  
    #是否单调将  
    isAllHu = False  
    needNum = 0  
    for i in range(0,4):  
        needNum += ndHunArr[i]  
    if curHunNum - needNum == 1:  
        isAllHu = True  
    if isAllHu:  
        tingArr.extend(tmpArr)  
        return  tingArr  
  
    for i in range(0,4):  
        setTmp = set(sptArr[i+1])  
        for x in setTmp:  
            t = []  
            t.extend(sptArr[i+1])  
            t.remove(x)  
            # 将  
            needNum = 0  
            for j in range(0,4):  
                if(i != j):  
                    needNum = needNum + ndHunArr[j]  
            if needNum <= curHunNum and x not in tingArr:  
                if canHu(curHunNum-needNum,t):  
                    tingArr.append(x)  
            # print callTime  
            # 扑  
            for j in range(0,4):  
                if len(sptArr[j+1]) == 0:  
                    continue  
                if(i != j):  
                    needNum = 0  
                    for k in range(0,4):  
                        if(k != i):  
                            if(k == j):  
                                needNum += jaNdHunArr[k]  
                            else:  
                                needNum += ndHunArr[k]  
                    if needNum <= curHunNum and x not in tingArr:  
                        g_NeedHunCount = 4  
                        getNeedHunInSub(t, 0 )  
                        if g_NeedHunCount <= curHunNum - needNum:  
                            tingArr.append(x)  
                            # print str(callTime) + 10*'-'  
    return tingArr


def main():
    majmap = {"101":"一万","102":"二万","103":"三万","104":"四万","105":"五万","106":"六万","107":"七万","108":"八万","109":"九万",  
          "201":"一饼","202":"二饼","203":"三饼","204":"四饼","205":"五饼","206":"六饼","207":"七饼","208":"八饼","209":"九饼",  
          "301":"一条","302":"二条","303":"三条","304":"四条","305":"五条","306":"六条","307":"七条","308":"八条","309":"九条",  
          "401":"东风","402":"西风","403":"南风","404":"北风","405":"红中","406":"发财","407":"白板"} 
    samArr = [405,202,203,203,204,205,302,302,303,303]
    tingNumArr = [405,202,203,203,204,205,301,302,302,303,303]
    import datetime
    global callTime
    callTime = 0  
    tingArr = getTingNumArr(tingNumArr,405)
    begin = datetime.datetime.now()  
    end = datetime.datetime.now()  
    runTime = end-begin  
    print tingArr
    

    #samArr = [111, 111, 111, 111, 214, 214, 214, 214, 315, 315, 315, 315, 118, 119, 119 ]
    #print testHu(112, samArr, 111) 
    samArr = [405,202,203,203,204,205,302,302,303,303]
    print getTingArr(samArr,405)

if __name__ == '__main__':
    main()  